﻿// Copyright © 2011 Paul Vanukoff (pvanukoff@gmail.com)

using System.Collections.Generic;
using Bravura.Core.PluginLib;
using Bravura.Core.Common;

namespace Bravura.Native.PluginBase
{
	/// <summary>
	/// Base class for audio plugins.
	/// </summary>
	public abstract class AudioPlugin : AudioPluginBase
	{
		/// <summary>
		/// Static NullBuffer instance.
		/// </summary>
		static NullBuffer NullBuffer = new NullBuffer();

		#region IAudioPlugin

		/// <summary>
		/// Default constructor.
		/// </summary>
		protected AudioPlugin(IAudioPluginHost host, int sampleRate) : base(host, sampleRate)
		{
		}

		/// <summary>
		/// Configures the plugin.
		/// </summary>
		public override void Configure(List<IConfigItem> configuration)
		{
			foreach (IConfigItem item in configuration)
			{
				string itemName = item.GetName();
				if (this.HasProperty(itemName))
				{
					bool set = false;
					string itemVal = item.GetValue();
					List<IConfigItem> subItems = item.GetChildItems();
					if (!string.IsNullOrEmpty(itemVal))
					{
						set = this.SetPropertyValue(itemName, itemVal);
					}
					else if (subItems != null && subItems.Count > 0)
					{
						set = this.SetPropertyValue(itemName, subItems);
					}
					if (!set)
					{
						Configure(item);
					}
				}
			}
		}

		/// <summary>
		/// Set a configuration item that the primary Configure() method was not able to.
		/// </summary>
		protected virtual void Configure(IConfigItem item)
		{
		}

		/// <summary>
		/// Sets a value of a plugin (run-time) setting.
		/// </summary>
		public override void SetPluginSetting(string key, string value)
		{
			this.SetPropertyValue(key, value);
		}

		/// <summary>
		/// Sets a value of a plugin (run-time) control.
		/// </summary>
		public override void SetPluginControl(string key, double value)
		{
			this.SetPropertyValue(key, value);
		}

		#endregion

		#region IAudioSource / IAudioTarget

		private Dictionary<int, IAudioBuffer> _outputBuffers = new Dictionary<int, IAudioBuffer>();
		private Dictionary<int, IAudioBuffer> _inputBuffers = new Dictionary<int, IAudioBuffer>();

		public IAudioBuffer GetOutputBuffer(int channelNum)
		{
			return _outputBuffers.ContainsKey(channelNum) ? _outputBuffers[channelNum] : NullBuffer;
		}

		public IAudioBuffer GetInputBuffer(int channelNum)
		{
			return _inputBuffers.ContainsKey(channelNum) ? _inputBuffers[channelNum] : NullBuffer;
		}

		public void AssignOutputBuffer(int channelNum, IAudioBuffer buffer)
		{
			_outputBuffers[channelNum] = buffer;
		}

		public void AssignInputBuffer(int channelNum, IAudioBuffer buffer)
		{
			_inputBuffers[channelNum] = buffer;
		}

		#endregion
	}
}
